#include <iostream>
#include <string>
#include <cassert>
#include <list>
#include <fstream>
#include <algorithm>

#include <gtkmm.h>
#include <gtkglmm.h>

#include <GL/gl.h>
#include <GL/glu.h>

#include "application.h"
#include "unittest.h"

using namespace std;

std::string genEnumName(const std::string & nodeName)
{
	std::string out = nodeName;
	std::transform(out.begin(), out.end(), out.begin(), ::toupper);
	for (int i = 0; i < out.size(); i++)
	{
		if (out[i] == ' ')
			out[i] = '_';
	}
	return out;
}

void codeGen()
{
	std::map <std::string, SceneNode> nodeTypes;
	if (joeserialize::LoadObjectFromFile("nodeTypes", "nodetypes.txt", nodeTypes, false, true, std::cout, std::cerr))
	{
		std::ofstream f("nodetypes.h");
		f <<	"#ifndef _NODETYPES_H\n"
				"#define _NODETYPES_H\n\n"
				"#include <string>\n\n"
				"struct NodeTypes\n"
				"{\n"
				"\tenum NODETYPE\n"
				"\t{\n";
		
		for (std::map <std::string, SceneNode>::const_iterator i = nodeTypes.begin(); i != nodeTypes.end(); i++)
		{
			f << "\t\t" << genEnumName(i->first) << ",\n";
		}
		
		f <<	"\t\tUNKNOWN\n"
				"\t};\n\n"
				"\tstatic NODETYPE getType(const std::string & type)\n"
				"\t{\n";
		
		for (std::map <std::string, SceneNode>::const_iterator i = nodeTypes.begin(); i != nodeTypes.end(); i++)
		{
			f << "\t\t";
			if (i != nodeTypes.begin())
				f << "else ";
			f << "if (type == \"" << i->first << "\") return " << genEnumName(i->first) << ";\n";
		}
		
		f <<	"\t\telse return UNKNOWN;\n"
				"\t}\n\n"
				"\tstatic std::string getType(NODETYPE type)\n"
				"\t{\n"
				"\t\tswitch (type)\n"
				"\t\t{\n";
		
		for (std::map <std::string, SceneNode>::const_iterator i = nodeTypes.begin(); i != nodeTypes.end(); i++)
		{
			f << "\t\t\tcase " << genEnumName(i->first) << ":\n";
			f << "\t\t\treturn \"" << i->first << "\";\n\n";
		}
		
		f <<	"\t\t}\n\n"
				"\t\treturn \"unknown\";\n"
				"\t}\n"
				"};\n\n"
				"#endif\n";
				
		std::cout << "Wrote nodetypes.h" << std::endl << std::endl;
	}
}

int main(int argc, char ** argv)
{
	if (argc == 2 && std::string(argv[1]) == "-codegen")
	{
		codeGen();
		return 0;
	}
	else if (argc == 2 && std::string(argv[1]) == "-test")
	{
		QT_RUN_TESTS;
	}
	else
	{
		Gtk::Main kit(argc, argv);
		Gtk::GL::init(argc, argv);
		Gdk::GL::init(argc, argv);
		
		Application app(argc, argv);
		
		int result = app.run();
		std::cout << std::endl;
		return result;
	}
}

